home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
system
/
idrv01.zip
/
IDRV.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-11-25
|
26KB
|
1,042 lines
NAME Device_Driver_Installer
TITLE Idrv.asm
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::;
; 18-11-1991 ;
; Idrv.asm (v1.06) ;
; compiled with Turbo Assembler v1.0 ;
; by Janusz Wojcik ;
; Lublin,Poland. ;
;..............................................................................;
ASSUME DS:st_seg, SS:st_seg ,CS:st_seg ,ES:st_seg
st_seg SEGMENT
ORG 100h
start:
mov ax,es
dec ax
mov es,ax ;ES = ES - 1
mov ax,word ptr es:3 ;get size of memory block from MCB
push ax
mov bx,es
add ax,bx ;compute address of the end of memory block
mov bx,LEN + 15 ;compute size of the program ...
mov cl,4
shr bx,cl ; ... in paragraphs
sub ax,bx ;calculate new address of program's beginning
mov jmp_seg,ax ;save it
mov es,ax
;.......................................................
pop ax
mov dx,10h ;add PSP size
add dx,bx
sub ax,dx
cmp ax,1000h ;some drivers set stack at the ...
; ... end of the segment !!!
ja move_code ;jump if more than 64KB left
lea dx,too_small
mov ah,9
int 21h
mov ah,4ch ;EXIT
mov al,1 ;Set return code
int 21h
;.......................................................
move_code:
mov cx,LEN
mov di,0
mov si,offset pr_end
cld
rep movsb ;move program into upper memory
jmp dword ptr jmp_offs ;and go there
too_small db 'IDrv: Too small memory!',cr,lf,lf,'$'
jmp_offs dw 0
jmp_seg dw 0
ALIGN 16
pr_end equ $
st_seg ends
;*******************************************************************************
ASSUME DS:code, SS:code ,CS:code ,ES:code
code SEGMENT Byte Public 'code'
new_seg equ $
mov ax,cs
cli
mov ss,ax ;Set own stack
mov sp,offset EOS
sti
mov ax,ds
push cs
pop ds ;DS = CS
mov our_seg,ax
jmp starter ; jump over data
own_stack db 157 dup(0)
EOS equ $ ; End Of Stack
;...............................................................................
device_header struc
next_offs dw ?
next_seg dw ?
dev_attr dw ?
dev_strategy dw ?
dev_interrupt dw ?
name_unit db 8 dup(?)
device_header ends
;Idrv Control Block
icb struc
signature db 7 dup(?)
xms_marker db 3 dup(?)
prv_xms_offs dw ?
prv_xms_seg dw ?
xms_handle dw ?
icb ends
.errnz 16 - SIZE icb
;...............................................................................
lf equ 0ah ; line feed
cr equ 0dh ; carriage return
ZERO equ 0
INIT equ 0
TAB equ 9
DIB_SIZE equ 21h
FIRST_DIB equ 26h
FIRST_DA equ 3ch
NUM_OF_DRV equ 46h
TOTAL_NUM equ 47h
MAX_SECTOR equ 36h
JMP_SHORT equ 3ebh
JMP_FAR equ 0eah
;...............................................................................
; the program body
;..............................................................................
ldrv:
call load_drv
jnc idev
jmp exit
idev:
mov es,dos_seg
mov al,byte ptr es:NUM_OF_DRV ;Get real number of drives
mov drive_num,al ;Set unit number in Req. Header
call init_dev ;INIT device
jnc modify_mem
call restore_xms ;restore previous state of original XMS handler
lea dx,err3
jmp exit
modify_mem:
call restore_xms ;restore previous state of original XMS handler
test flags,UMB_USED ;Driver in other mem. block ?
jz create_cb ;No,skip
mov bx,ending_offset
add bx,15
rcr bx,1
mov cl,3
shr bx,cl
add bx,ending_segment
mov ax,dev_seg
dec ax ;take into account ICB size!
sub bx,ax ;BX - size of mem. block in paragraphs
mov es,ax ;ES - seg. of the block
mov ah,4ah ;Modify alloc. mem. block
int 21h
jnc create_cb
lea dx,err7
jmp exit_err
create_cb:
mov ax,dev_seg
mov es,ax
mov bx,drv_beg
call create_icb ;create Idrv Control Block
mov ax,es:dev_attr[bx]
test ah,80h ;Character device ?
jnz ldev ;Yes,jump to link device headers
cmp units,ZERO ;Error during INIT ?
jnz check_CDS ;No
lea dx,err3
jmp exit ;Yes,jump to quit
check_CDS:
call check_DA
jc exit_err
DIB_creation:
call seek_last ;Seek the last DIB
mov lastDIB_offs,bx
mov lastDIB_seg,es
test flags,UMB_USED ;driver in other mem.block ?
jz DIB_after_drv ;No,jump
mov ax,our_seg
add ax,10h ;add PSP size
jmp set_DIB_addr
DIB_after_drv:
mov ax,ending_offset
add ax,15
mov cl,4
shr ax,cl
add ax,ending_segment
set_DIB_addr:
mov DIB_seg,ax
mov DIB_offs,ZERO
mov cl,units ;CX = number of units
xor ch,ch
mov dl,es:[bx] ;DL = last drive#
mov dh,0ffh
DIB_continue:
inc dl ;Set drive#
inc dh ;Set unit#
call create_DIB ;Create Disk Info Block
jnc DA_creation
call restore ;Restore previous state of DIB & DA chains
jmp exit_err
DA_creation:
call create_DA ;Create Disk Area
les bx,dword ptr DIB_offs
add DIB_offs,DIB_SIZE ;Set new DIB address
loop DIB_continue
ldev: call link_dev ;Link device headers
jmp exit_OK
exit_err:
call free_xmem
call print_msg
exit_OK:
mov ax,our_seg
mov es,ax
mov es,es:2ch
mov ah,49h ; Free allocated memory (environment)
int 21h
test flags,UMB_USED ; Driver in UMB ?
jz drv_not_high ; No,jump
mov dx,100h ; size of PSP
add dx,ad_mem
add dx,15
rcr dx,1
mov cl,3
shr dx,cl
jmp term_resident
drv_not_high:
mov dx,ending_offset ;Compute address of ...
add dx,ad_mem
add dx,15
rcr dx,1
mov cl,3
shr dx,cl
add dx,ending_segment
inc dx ; (add one para)
mov ax,our_seg
sub dx,ax ; ... program end
term_resident:
xor al,al ; set 0 for return code
mov ah,31h ;Terminate and remain resident
int 21h
exit:
call print_msg
exit_no_print:
mov ah,4ch ;EXIT
mov al,1 ;Set return code
int 21h
;..............................................................................
; create_icb:
; creates Idrv Control Block before Device Header
; Input:
; ES:BX - Device Header address
;..............................................................................
create_icb proc near
push es
mov ax,es
dec ax
mov es,ax
mov si,offset sign
mov cx,SIG_LEN
mov di,bx
cld
rep movsb ;place signature
mov ax,handle
mov word ptr es:xms_marker[bx],ax ;the word will be ...
; ... 0 if handle is 0
cmp ax,ZERO
je xms_not_used
mov word ptr es:xms_handle[bx],ax
mov byte ptr es:xms_marker[bx],'X' ;signal that XMS was used
mov word ptr es:xms_marker[bx + 1],'SM'
mov ax,prv_offs
mov word ptr es:prv_xms_offs[bx],ax
mov ax,prv_seg
mov word ptr es:prv_xms_seg[bx],ax
xms_not_used:
pop es
ret
create_icb endp
page;..........................................................................
; link_dev: .......
; links Device Header of the driver with the chain of .......
; Device Headers of the rest drivers ....... .......
;..............................................................................
link_dev:
mov es,dos_seg
mov si,48h
push es
les si,dword ptr es:[si] ;Address of next dev. header
mov bx,drv_beg
mov ax,dev_seg
push ds
mov ds,ax
mov next_offs[bx],si
mov next_seg[bx],es
mov bx,dev_attr[bx] ;get dev.attribute for later
pop ds
pop es
cli
mov es:48h,word ptr ZERO
mov ax,dev_seg
mov es:4ah,ax
sti
test bl,1 ;Is it Stdin device ?
jz test_clk ;No,jump
mov es:32h,word ptr ZERO ;Change pointer to ...
mov es:34h,ax ; ... Stdin
les bx,es:02ah ;Get address of DOS file table
add bx,dos_dep ;change entry length of OFT if necessary
mov es:[bx + 042h],word ptr ZERO ;Change address of dev.header ...
mov es:[bx + 044h],ax ; ... in Open Files Table
jmp quit_link
test_clk: test bl,8 ;Is it clock device ?
jz quit_link ;No,jump
mov es:2eh,word ptr ZERO
mov es:30h,ax
quit_link:
ret
;..............................................................................
; load_drv: ....